﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TileMap
{
    public class BitmapMatrix : IDisposable , IEnumerable<Bitmap> , IEnumerator<Bitmap>
    {
        private Bitmap[,] _matrix = null;
        private int _rowsCurrent = 0;
        private int _columnsCurrent = 0;

        /// <summary>
        /// 行数
        /// </summary>
        public int Rows { get; private set; }
        /// <summary>
        /// 列数
        /// </summary>
        public int Columns { get; private set; }
        /// <summary>
        /// 整体分辨率
        /// </summary>
        public Size Resolution { get; private set; }
        /// <summary>
        /// 单张图片的分辨率
        /// </summary>
        public Size SingleResolution { get; private set;}

        public Bitmap Current
        {
            get
            {
                return _matrix[_rowsCurrent, _columnsCurrent];
            }
        }

        object IEnumerator.Current
        {
            get
            {
                return _matrix[_rowsCurrent, _columnsCurrent];
            }
        }

        public Bitmap this[int rows , int columns]
        {
            get
            {
                return _matrix[rows, columns];
            }
        }

        public BitmapMatrix(Bitmap[,] matrix) 
        {
            _matrix = matrix;
            Rows = matrix.GetLength(0);
            Columns = matrix.GetLength(1);
            SingleResolution = matrix[0, 0].Size;
            Resolution = new Size(Rows * SingleResolution.Width, Columns * SingleResolution.Height);
        }

        public BitmapMatrix(int rows , int columns , Size singleResolution , PixelFormat format)
        {
            _matrix = MapFactory.CreateBitmapMatrix(rows, columns, singleResolution, format);
            Rows = rows;
            Columns = columns;
            SingleResolution = singleResolution;
            Resolution = new Size(Rows * singleResolution.Width, Columns * singleResolution.Height);
        }

        public BitmapMatrix(string direcotry)
        {

        }

        /// <summary>
        /// 将矩阵中的图片保存到文件夹
        /// </summary>
        /// <param name="directory"></param>
        public void Save(string directory)
        {
            for (int i = 0; i < Rows; i++)
            {
                for (int j = 0; j < Columns; j++)
                {
                    string filename = string.Format("{0},{1}", i, j);
                    _matrix[i, j].Save(filename, ImageFormat.Bmp);
                }
            }
        }

        public Graphics CreateGraphics(int row , int column)
        {
            if (row < Rows && column < Columns)
            {
                return Graphics.FromImage(_matrix[row, column]);
            }
            else
            {
                throw new ArgumentOutOfRangeException("index out of range");
            }
        }

        public override string ToString()
        {
            return string.Format("Rows:{0} , Columns:{1} , Resolution:{2}*{3}", Rows, Columns, Resolution.Width, Resolution.Height);
        }

        #region IDisposable Support
        private bool disposedValue = false; // 要检测冗余调用

        protected virtual void Dispose(bool disposing)
        {
            if (!disposedValue)
            {
                if (disposing)
                {
                    // TODO: 释放托管状态(托管对象)。
                    for (int i = 0; i < Rows; i++)
                    {
                        for (int j = 0; j < Columns; j++)
                        {
                            _matrix[i, j].Dispose();
                            _matrix[i, j] = null;
                        }
                    }
                    _matrix = null;
                }

                // TODO: 释放未托管的资源(未托管的对象)并在以下内容中替代终结器。
                // TODO: 将大型字段设置为 null。

                disposedValue = true;
            }
        }

        // TODO: 仅当以上 Dispose(bool disposing) 拥有用于释放未托管资源的代码时才替代终结器。
        // ~BitmapMatrix() {
        //   // 请勿更改此代码。将清理代码放入以上 Dispose(bool disposing) 中。
        //   Dispose(false);
        // }

        // 添加此代码以正确实现可处置模式。
        public void Dispose()
        {
            // 请勿更改此代码。将清理代码放入以上 Dispose(bool disposing) 中。
            Dispose(true);
            // TODO: 如果在以上内容中替代了终结器，则取消注释以下行。
            // GC.SuppressFinalize(this);
        }
        #endregion

        public IEnumerator<Bitmap> GetEnumerator()
        {
            int count = Rows * Columns;
            for (int i = 0; i < count; i++)
            {
                yield return _matrix[i / Rows, i % Columns];
            }
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return _matrix.GetEnumerator();
        }

        public bool MoveNext()
        {
            _columnsCurrent++;
            if (_columnsCurrent >= Columns)
            {
                _columnsCurrent = 0;
                _rowsCurrent++;
            }
            if (_rowsCurrent >= Rows)
            {
                return false;
            }
            return true;
        }

        public void Reset()
        {
            _columnsCurrent = 0;
            _rowsCurrent = 0;
        }
    }
}
